<?php

namespace W3;

!defined('W3_ROOT_DIR') AND exit;

/**
 * 系统工具类
 *
 * @author edikud
 * @date 2022/10/22
 * @copyright Copyright (c) 2022 W3 (http://www.mcooo.com)
 * @license GNU General Public License 2.0
 */

class Token
{

    protected static $token = '';

    /**
     * 创建一个会过期的Token
     *
     * @param $secret
     * @return string
     */
    public static function expire($secret): string
    {
        return sha1($secret . '&' . time());
    }

    /**
     * 在时间范围内验证token
     *
     * @param $token
     * @param $secret
     * @param int $timeout
     * @return bool
     */
    public static function expireValidate($token, $secret, int $timeout = 5): bool
    {
        $now = time();
        $from = $now - $timeout;

        for ($i = $now; $i >= $from; $i--) {
            if (sha1($secret . '&' . $i) == $token) {
                return true;
            }
        }

        return false;
    }

    /**
     * 设置token
     *
     * @param string $token token
     * @return void
     */
    public static function set($token)
    {
        static::$token = $token;
    }

    /**
     * 获取token
     *
     * @param string $suffix 后缀
     * @return string
     */
    public static function get($suffix)
    {
        return md5(static::$token . '&' . $suffix);
    }
	
    /**
     * 生成带token的路径
     *
     * @param $path
     * @return string
     */
    public static function buildUrl($path = '', ?string $url = null): string
    {
        $parts = parse_url($path);
        $params = [];

        if (!empty($parts['query'])) {
            parse_str($parts['query'], $params);
        }

        $params['_'] = static::get($url ?:  Request::instance()->url(true));
        $parts['query'] = http_build_query($params);

        return Util::buildUrl($parts);
    }
	
    /**
     * 检查令牌
     *
     * @param $url
     * @return bool
     */
    public static function validate(?string $url = null)
    {
        if (Request::instance()->get('_') == static::get($url ?:  Request::instance()->referer())) {
            return true;
        }
		
		return false;
    }

}